package com.hello.file.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.hello.file.config.AliyunConfig;
import com.hello.file.utils.FileLogUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 阿里云 OSS 文件存储
 * 
 * @author hello
 */
@Service
public class AliyunSysFileServiceImpl implements ISysFileService
{
    private static final Logger log = LoggerFactory.getLogger(AliyunSysFileServiceImpl.class);
    
    @Autowired
    private AliyunConfig aliyunConfig;

    /**
     * 文件上传接口
     * 
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception
    {
        // 获取原始文件名
        String originalFilename = file.getOriginalFilename();
        
        // 使用文件日志工具记录开始上传
        FileLogUtils.logFileUploadStart("阿里云OSS", file, aliyunConfig.getBucketName());
        
        // 生成文件名
        String fileName = getFilePath(originalFilename);
        log.info("生成阿里云OSS存储路径: {}", fileName);
        
        // 创建OSS客户端
        OSS ossClient = new OSSClientBuilder().build(
                aliyunConfig.getEndpoint(),
                aliyunConfig.getAccessKeyId(),
                aliyunConfig.getAccessKeySecret());
        
        try
        {
            InputStream inputStream = file.getInputStream();
            
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(inputStream.available());
            metadata.setCacheControl("no-cache");
            metadata.setHeader("Pragma", "no-cache");
            metadata.setContentType(getContentType(originalFilename));
            metadata.setContentDisposition("inline;filename=" + originalFilename);
            
            log.info("准备上传文件到阿里云OSS，ContentType: {}", metadata.getContentType());
            
            // 上传文件
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    aliyunConfig.getBucketName(), fileName, inputStream, metadata);
            ossClient.putObject(putObjectRequest);
            
            // 返回上传后的访问路径
            String url = aliyunConfig.getDomain() + "/" + fileName;
            
            // 使用文件日志工具记录上传成功
            FileLogUtils.logFileUploadSuccess("阿里云OSS", fileName, url);
            
            return url;
        }
        catch (Exception e)
        {
            // 使用文件日志工具记录上传失败
            FileLogUtils.logFileUploadError("阿里云OSS", originalFilename, e.getMessage());
            throw e;
        }
        finally
        {
            ossClient.shutdown();
        }
    }
    
    /**
     * 生成文件路径
     */
    private String getFilePath(String fileName)
    {
        // 使用日期构建目录结构：年/月/日/
        LocalDate now = LocalDate.now();
        String datePath = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        
        // 使用UUID生成唯一文件名
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        
        // 获取文件后缀
        int lastIndex = fileName.lastIndexOf(".");
        String fileExtension = "";
        if (lastIndex > 0)
        {
            fileExtension = fileName.substring(lastIndex);
        }
        
        return datePath + "/" + uuid + fileExtension;
    }
    
    /**
     * 获取文件内容类型
     */
    private String getContentType(String fileName)
    {
        // 检查文件名是否为空或不包含点号
        if (fileName == null || fileName.lastIndexOf(".") == -1) {
            // 如果文件名为空或没有扩展名，返回默认的MIME类型
            return "application/octet-stream";
        }
        
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        
        if (".bmp".equalsIgnoreCase(fileExtension)) return "image/bmp";
        if (".gif".equalsIgnoreCase(fileExtension)) return "image/gif";
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)) return "image/jpeg";
        if (".png".equalsIgnoreCase(fileExtension)) return "image/png";
        if (".html".equalsIgnoreCase(fileExtension)) return "text/html";
        if (".txt".equalsIgnoreCase(fileExtension)) return "text/plain";
        if (".vsd".equalsIgnoreCase(fileExtension)) return "application/vnd.visio";
        if (".ppt".equalsIgnoreCase(fileExtension) || ".pptx".equalsIgnoreCase(fileExtension)) return "application/vnd.ms-powerpoint";
        if (".doc".equalsIgnoreCase(fileExtension) || ".docx".equalsIgnoreCase(fileExtension)) return "application/msword";
        if (".xml".equalsIgnoreCase(fileExtension)) return "text/xml";
        if (".mp4".equalsIgnoreCase(fileExtension)) return "video/mp4";
        if (".mp3".equalsIgnoreCase(fileExtension)) return "audio/mp3";
        // 默认返回二进制流
        return "application/octet-stream";
    }
} 